In [1]:
import plotly.graph_objects as go
import plotly.figure_factory as ff
import numpy as np
import pandas as pd
import re
In [2]:
# plot force diagram
fig = go.Figure()
fig.add_shape(type='rect', x0=0, y0=1, x1=4, y1=3, fillcolor='rgba(133, 163, 201, 0.5)')
fig.add_scatter(x=np.linspace(-1,5, 20), y=np.ones(20)*3.5, line_color='black')
fig.add_scatter(x=np.linspace(-1,5, 20), y=np.ones(20)*0.5, line_color='black')
fig.add_annotation(x=-0.1, y=2, ax=-1, ay=2, xref='x', yref='y', axref='x', ayref='y',arrowhead=5, text=
                   r'$\require{color}{\color[rgb]{0.315209,0.728565,0.037706}p}$')
fig.add_annotation(x=4.1, y=2, ax=6, ay=2, xref='x', yref='y', axref='x', ayref='y', arrowhead=5, text=
                   r'$\require{color} {\color[rgb]{0.315209,0.728565,0.037706}p} + \frac{\partial \
                   {\color[rgb]{0.315209,0.728565,0.037706}p}}{\partial x} \delta x$')
fig.add_annotation(x=1, y=0.9, ax=3, ay=0.9, xref='x', yref='y', axref='x', ayref='y', arrowhead=5, 
                   text=r'$\require{color}{\color[rgb]{0.990308,0.800015,0.121270}\tau}$')
fig.add_annotation(x=3.5, y=3.25, ax=0.5, ay=3.25, xref='x', yref='y', axref='x', ayref='y', arrowhead=5, text=
                   r'$\require{color}{\color[rgb]{0.990308,0.800015,0.121270}\tau} + \frac{\partial \
                   {\color[rgb]{0.990308,0.800015,0.121270}\tau}}{\partial y} \delta y$')
fig.add_annotation(x=4, y=3.65, ax=0, ay=3.65, xref='x', yref='y', axref='x', ayref='y', arrowhead=5, 
                   text=r'$\require{color}{\color[rgb]{0.059472,0.501943,0.998465}v}$')
fig.add_scatter(x=[2], y=[0.4], mode='text', text=r'$\require{color}{\color[rgb]{0.059472,0.501943,0.998465}v}=0$')
fig.add_annotation(x=-1.2, y=3.5, ax=-1.2, ay=0.4, xref='x', yref='y', axref='x', ayref='y', arrowhead=5)
fig.add_scatter(x=[-1.3], y=[2], mode='text', text=r'$H$')
fig.update_layout(yaxis=dict(scaleanchor="x", scaleratio=1, showticklabels=False), xaxis=dict(showticklabels=False),
                  showlegend=False, plot_bgcolor='rgba(0, 0, 0, 0)')
fig.show()

Because the velocity is constant in the x direction and depends only on the vertical position $F_{x}=0$ and because velocity is zero in the y direction $F_{y}=0$ \ The shear stress on the fluid is a function only of y and the pressure is a function only of x, therefore in the y-direction $\require{color}\frac{\partial {\color[rgb]{0.990308,0.800015,0.121270}\tau}}{\partial x} = \frac{\partial {\color[rgb]{0.315209,0.728565,0.037706}p}}{\partial y} = 0$ \ In order for the x components of shear and pressure to sum to zero they must both be constant along their respective axes \ By using the above force diagram we can get a relationship between $\require{color}\frac{\partial {\color[rgb]{0.315209,0.728565,0.037706}p}}{\partial x}$ and $\require{color}\frac{\partial {\color[rgb]{0.990308,0.800015,0.121270}\tau}}{\partial y}$: \ \begin{equation} \require{color}F_{x} = 0 = {\color[rgb]{0.315209,0.728565,0.037706}p}\delta y - \ ({\color[rgb]{0.315209,0.728565,0.037706}p}+\frac{\partial {\color[rgb]{0.315209,0.728565,0.037706}p}}{\partial x} \delta x)\delta y - {\color[rgb]{0.990308,0.800015,0.121270}\tau}\delta x + ({\color[rgb]{0.990308,0.800015,0.121270}\tau} + \frac{\partial {\color[rgb]{0.990308,0.800015,0.121270}\tau}}{\partial y} \ \delta y)\delta x \longrightarrow \frac{\partial {\color[rgb]{0.315209,0.728565,0.037706}p}}{\partial x} = \frac{\partial {\color[rgb]{0.990308,0.800015,0.121270}\tau}}{\partial y} \end{equation} Because pressure is only a function of x and shear stress is only a function of y we can say the partial derivatives from above can be converted to total derivatives: $\require{color}\frac{d{\color[rgb]{0.315209,0.728565,0.037706}p}}{dx} = \frac{d{\color[rgb]{0.990308,0.800015,0.121270}\tau}}{dy}$ \ Furthermore we know the equation for shear stress: $\require{color}{\color[rgb]{0.990308,0.800015,0.121270}\tau} = {\color[rgb]{0.990448,0.502245,0.032881}\mu} \frac{d{\color[rgb]{0.059472,0.501943,0.998465}v}_{x}}{dy}$ so we can get a relationship between velocity and the pressure gradient: \begin{equation} \require{color}\frac{d}{dy}({\color[rgb]{0.990448,0.502245,0.032881}\mu} \frac{d{\color[rgb]{0.059472,0.501943,0.998465}v}_{x}}{dy}) = {\color[rgb]{0.990448,0.502245,0.032881}\mu} \frac{d^{2}{\color[rgb]{0.059472,0.501943,0.998465}v}_{x}}{dy^{2}} = \frac{d{\color[rgb]{0.315209,0.728565,0.037706}p}}{dx} \end{equation} For Couette flow we assume that the pressure gradient is zero, therefore: $\require{color}{\color[rgb]{0.990448,0.502245,0.032881}\mu} \frac{d^{2}{\color[rgb]{0.059472,0.501943,0.998465}v}_{x}}{dy^{2}} =0$ and we can assume a solution in the form $\require{color}{\color[rgb]{0.059472,0.501943,0.998465}v}=By+C$ Using the boundary conditions $\require{color}{\color[rgb]{0.059472,0.501943,0.998465}v}(0)=0$ and $\require{color}{\color[rgb]{0.059472,0.501943,0.998465}v}(H)={\color[rgb]{0.059472,0.501943,0.998465}V}$ we can find the solution $\require{color}{\color[rgb]{0.059472,0.501943,0.998465}v}={\color[rgb]{0.059472,0.501943,0.998465}V} \frac{y}{H}$

In [3]:
# define arbitary constants and the x,y, and velocity values
H=10
V=100
x=np.zeros(10)
y=np.linspace(0, H-1, 10)
v_x=V*(y/H)
v_y=np.zeros(10)
In [4]:
# plot vector diagram of the flow velocity profile
fig = ff.create_quiver(x=x, y=y, u=v_x, v=v_y, arrow_scale=0.05)
fig.update_layout(xaxis=dict(range=[-1, 11]))
fig.add_scatter(x=np.linspace(-1,10, 20), y=np.ones(20)*10, line_color='black')
fig.add_scatter(x=np.linspace(-1,10, 20), y=np.zeros(20), line_color='black')
fig.update_layout(yaxis=dict(scaleanchor="x", scaleratio=1, showticklabels=False), xaxis=dict(showticklabels=False),
                  showlegend=False, plot_bgcolor='rgba(0, 0, 0, 0)')
fig.show()

The plot above shows the velocity vectors at 9 points between the two walls, this shows how fast a particle within the fluid is moving at the point of the beginning of the arrow depending on the y position

In [5]:
# find the total time for the top particle to reach x=10 then calculate the distance each particle travels in that time
time = 20/v_x[9]
total_distance = time*v_x
In [6]:
# use time and distance information to show how the horizontal distance bewteen particles starting at the same place changes
fig = go.Figure()
frames = [go.Frame(data=[]) for k in range(50)]
for i, y_pos in enumerate(y[1:len(y)]):
    fig.add_scatter(x=np.linspace(0, 20, 20), y=np.ones(20)*y_pos, line_dash='dash', line_color='lightsteelblue')
    x_pos = np.linspace(0, total_distance[i+1], 50)
    for j,f in enumerate(frames):
        f.data += (go.Scatter(x=[x_pos[j]], y=[(np.ones(50)[j]*y_pos)], mode='markers', marker=dict(color='teal', size=10)),)

fig.update(frames=frames)

fig.update_layout(updatemenus = [dict(type='buttons', buttons=[dict(label='play', method='animate', 
                  args=[None, {'frame':{'duration':50}}])])], showlegend=False, xaxis=dict(range=[0,20]))

fig.add_scatter(x=np.linspace(0, 20, 20), y=np.ones(20)*H, line_color='black')
fig.add_annotation(x=18, y=10.25, ax=2, ay=10.25, xref='x', yref='y', axref='x', ayref='y', arrowhead=5, 
                   text=r'$\require{color}{\color[rgb]{0.059472,0.501943,0.998465}v}$')
fig.add_scatter(x=np.linspace(0, 20, 20), y=np.zeros(20), line_color='black')
fig.update_layout(yaxis=dict(scaleanchor="x", scaleratio=1, showticklabels=False), xaxis=dict(showticklabels=False),
                  showlegend=False, plot_bgcolor='rgba(0, 0, 0, 0)')
fig.show()
In [ ]: